import { defineStore } from "pinia";
import {
  type userType,
  store,
  router,
  resetRouter,
  routerArrays,
  storageLocal
} from "../utils";
import {
  type UserResult,
  type RefreshTokenResult,
  type LoginRequest,
  type LoginResponse,
  getLogin,
  refreshTokenApi,
  getUserMenus
} from "@/api/user";
import { useMultiTagsStoreHook } from "./multiTags";
import { type DataInfo, setToken, removeToken, userKey } from "@/utils/auth";
import { usePermissionStoreHook } from "./permission";
import type { Menu } from "@/api/menu";
import { de } from "element-plus/es/locales.mjs";

export const useUserStore = defineStore({
  id: "pure-user",
  state: (): userType => ({
    // 头像
    avatar: storageLocal().getItem<DataInfo<number>>(userKey)?.avatar ?? "",
    // 用户名
    username: storageLocal().getItem<DataInfo<number>>(userKey)?.username ?? "",
    // 昵称
    nickname: storageLocal().getItem<DataInfo<number>>(userKey)?.nickname ?? "",
    // 用户ID
    id: storageLocal().getItem<DataInfo<number>>(userKey)?.id ?? 0,
    // 页面级别权限
    roles: storageLocal().getItem<DataInfo<number>>(userKey)?.roles ?? [],
    // 按钮级别权限
    permissions:
      storageLocal().getItem<DataInfo<number>>(userKey)?.permissions ?? [],
    // 用户菜单
    menus: [] as Menu[],
    // 是否勾选了登录页的免登录
    isRemembered: false,
    // 登录页的免登录存储几天，默认7天
    loginDay: 7
  }),
  actions: {
    /** 存储头像 */
    SET_AVATAR(avatar: string) {
      this.avatar = avatar;
    },
    /** 存储用户名 */
    SET_USERNAME(username: string) {
      this.username = username;
    },
    /** 存储昵称 */
    SET_NICKNAME(nickname: string) {
      this.nickname = nickname;
    },
    /** 存储用户ID */
    SET_ID(id: number) {
      this.id = id;
    },
    /** 存储角色 */
    SET_ROLES(roles: Array<string>) {
      this.roles = roles;
    },
    /** 存储按钮级别权限 */
    SET_PERMS(permissions: Array<string>) {
      this.permissions = permissions;
    },
    /** 存储用户菜单 */
    SET_MENUS(menus: Menu[]) {
      // 确保菜单数据中没有null的children
      this.menus = this.normalizeMenuChildren(menus);
    },
    /**
     * 规范化菜单数据，确保children不为null
     */
    normalizeMenuChildren(menus: any[]): any[] {
      if (!menus || !Array.isArray(menus)) return [];

      return menus.map(menu => {
        if (!menu) return menu;

        // 创建新对象，避免修改原始对象
        const newMenu = { ...menu };

        // 将null的children替换为空数组
        if (newMenu.children === null) {
          newMenu.children = [];
        } else if (Array.isArray(newMenu.children)) {
          // 递归处理子菜单
          newMenu.children = this.normalizeMenuChildren(newMenu.children);
        } else {
          // 其他情况(undefined等)设为空数组
          newMenu.children = [];
        }

        return newMenu;
      });
    },
    /** 存储是否勾选了登录页的免登录 */
    SET_ISREMEMBERED(bool: boolean) {
      this.isRemembered = bool;
    },
    /** 设置登录页的免登录存储几天 */
    SET_LOGINDAY(value: number) {
      this.loginDay = Number(value);
    },
    /** 登入 */
    async loginByUsername(data: LoginRequest) {
      return new Promise<LoginResponse>((resolve, reject) => {
        getLogin(data)
          .then(async res => {
            if (res.code === 0) {
              // 检查响应数据的完整性
              console.log("登录接口返回的完整数据:", res);

              // 确保user对象存在
              if (!res.data || !res.data.user) {
                console.error("登录接口返回的数据缺少user对象");
                reject(new Error("登录响应数据格式错误"));
                return;
              }

              // 必要的token检查
              // if (!res.data.accessToken) {
              //   console.error("登录接口返回的数据缺少accessToken");
              //   reject(new Error("登录响应数据缺少token"));
              //   return;
              // }

              // 设置角色
              const roleKey = `role_${res.data.user.role_id}`;
              const roles = [roleKey];

              // 构造完整的token数据 (使用类型断言)
              const tokenData = {
                accessToken: res.data.accessToken,
                refreshToken: res.data.refreshToken || "",
                expires: res.data.expires || new Date().toISOString(),
                user: res.data.user,
                id: res.data.user.id, // 明确设置用户ID
                roles: roles, // 明确设置角色
                // 预处理权限数据，确保在setToken函数中能被正确处理
                permissions: res.data.user.permissions && Array.isArray(res.data.user.permissions)
                  ? this.extractButtonPermissions(res.data.user.permissions)
                  : []
              } as any;

              console.log("准备传递给setToken的数据:", tokenData);

              // 先设置store中的数据，防止setToken中的循环引用问题
              this.SET_USERNAME(res.data.user.username);
              this.SET_NICKNAME(res.data.user.nickname);
              this.SET_AVATAR(res.data.user.avatar || "");
              this.SET_ROLES(roles);
              this.SET_ID(res.data.user.id); // 设置用户ID

              // 如果有菜单权限数据
              if (res.data.user.permissions && Array.isArray(res.data.user.permissions)) {
                // 保存菜单 - 规范化菜单数据
                const normalizedMenus = this.normalizeMenuChildren(res.data.user.permissions);
                this.SET_MENUS(normalizedMenus);

                // 提取按钮权限
                const buttonPerms = this.extractButtonPermissions(normalizedMenus);
                console.log("提取的按钮权限:", buttonPerms);
                this.SET_PERMS(buttonPerms);

                // 生成动态路由
                const dynamicRoutes = this.generateRoutes(normalizedMenus);
                console.log("生成的动态路由:", dynamicRoutes);

                // 更新权限存储
                try {
                  usePermissionStoreHook().handleWholeMenus(dynamicRoutes);
                } catch (error) {
                  console.error("处理路由菜单失败:", error);
                }
              } else {
                console.warn("登录接口返回的用户没有权限数据");
              }

              // 调用setToken函数保存所有信息
              setToken(tokenData);

              // 立即检查localStorage是否保存成功
              const storedUserInfo = storageLocal().getItem(userKey);
              console.log("保存后检查localStorage中的用户信息:", storedUserInfo);

              resolve(res);
            } else {
              reject(res);
            }
          })
          .catch(error => {
            console.error("登录接口调用失败:", error);
            reject(error);
          });
      });
    },
    /** 从菜单权限中提取按钮权限 */
    extractButtonPermissions(menus: any[]): string[] {
      if (!menus || !Array.isArray(menus)) {
        return [];
      }

      const buttonPerms: string[] = [];

      // 递归处理菜单树
      const processMenus = (menuItems: any[]) => {
        if (!menuItems || !Array.isArray(menuItems)) return;

        menuItems.forEach(menu => {
          if (!menu) return;

          // 处理当前菜单的按钮权限
          if (menu.meta && menu.meta.auths && Array.isArray(menu.meta.auths)) {
            // 可以格式化为 "moduleName:btnName" 格式
            const modulePrefix = menu.name || 'common';
            menu.meta.auths.forEach(auth => {
              // 可以添加模块前缀，也可以直接使用auth值
              buttonPerms.push(`${modulePrefix}:${auth}`);
              // 也存储原始权限值，确保兼容性
              buttonPerms.push(auth);
            });
          }

          // 处理子菜单 - 确保children不为null
          if (menu.children === null) {
            // 不处理null值
            return;
          } else if (Array.isArray(menu.children) && menu.children.length > 0) {
            processMenus(menu.children);
          }
        });
      };

      processMenus(menus);

      // 添加特殊权限，确保兼容性
      if (buttonPerms.length > 0) {
        buttonPerms.push('*:*:*'); // 全局通配符权限
      }

      return buttonPerms;
    },
    /** 获取用户菜单 */
    async getUserMenus() {
      try {
        const res = await getUserMenus();
        if (res.code === 0) {
          // 确保菜单数据中没有null的children
          const normalizedMenus = this.normalizeMenuChildren(res.data);
          this.SET_MENUS(normalizedMenus);

          // 处理菜单生成路由
          const dynamicRoutes = this.generateRoutes(normalizedMenus);
          usePermissionStoreHook().handleWholeMenus(dynamicRoutes);

          return Promise.resolve(normalizedMenus);
        } else {
          return Promise.reject(res.msg);
        }
      } catch (error) {
        return Promise.reject(error);
      }
    },
    /** 生成路由 */
    generateRoutes(menus: Menu[]) {
      if (!menus || !Array.isArray(menus) || menus.length === 0) {
        console.warn("生成路由时传入的菜单数据为空");
        return [];
      }

      console.log("生成路由，输入菜单数据:", menus);
      const dynamicRoutes = [];
      const existingNames = new Set<string>(); // 用于检查路由名称是否重复

      function formatMenu(menu: Menu, parentPath: string = "", depth: number = 0) {
        if (depth > 5) { // 防止无限递归
          console.warn("路由嵌套深度超过5层，可能存在循环引用:", menu);
          return null;
        }

        if (!menu || !menu.path) {
          console.warn("菜单项缺少path字段:", menu);
          return null;
        }

        let name = menu.name;

        // 处理路由名称冲突
        if (existingNames.has(name)) {
          const newName = `${name}_${Date.now().toString().substring(8)}`;
          console.warn(`路由名称 "${name}" 重复，自动重命名为 "${newName}"`);
          name = newName;
        }
        existingNames.add(name);

        // 处理组件
        let component = null;
        if (!menu.component) {
          component = () => import("@/layout/index.vue");
        } else if (menu.component === 'LAYOUT') {
          component = () => import("@/layout/index.vue");
        } else {
          // 特定路由的组件处理
          if (name === 'PermissionManage' || name.includes('Permission')) {
            component = () => import("@/layout/index.vue");
          } else if (name === 'RoleManagement') {
            component = () => import("@/views/permission/roles/index.vue");
          } else if (name === 'UserManagement') {
            component = () => import("@/views/permission/users/index.vue");
          } else if (name === 'MenuManagement') {
            component = () => import("@/views/permission/menus/index.vue");
          } else {
            // 默认情况
            component = () => import("@/layout/index.vue");
          }
        }

        // 规范化路径
        let path = menu.path;
        if (path.startsWith('/') && parentPath && !path.startsWith(parentPath)) {
          // 如果是绝对路径且不是以父路径开头，保持原样
        } else if (!path.startsWith('/') && parentPath) {
          // 如果是相对路径且有父路径，拼接成绝对路径
          path = `${parentPath}/${path}`.replace(/\/+/g, '/');
        }
        // 构建路由对象
        const route = {
          path,
          name,
          component,
          meta: {
            ...((menu.meta || {}) as any),
            title: menu.meta?.title || menu.title || name,
            icon: menu.meta?.icon || menu.icon,
            showLink: true,
            roles: [] as string[],
            rank: menu.meta?.rank || 0
          },
          children: undefined
        };

        // 处理子菜单 - 确保children不为null
        if (menu.children === null) {
          // 如果children为null，则移除children属性或赋值为空数组
          route.children = [];
        } else if (Array.isArray(menu.children) && menu.children.length > 0) {
          const formattedChildren = menu.children
            .map(child => formatMenu(child, path, depth + 1))
            .filter(Boolean); // 过滤掉null

          if (formattedChildren.length > 0) {
            route.children = formattedChildren;
          } else {
            route.children = []; // 如果过滤后没有子项，设置为空数组
          }
        }

        console.log(`生成路由项 [${depth}]: ${path} (${name})`);
        return route;
      }

      // 处理每个顶级菜单
      for (const menu of menus) {
        const formattedMenu = formatMenu(menu);
        if (formattedMenu) {
          dynamicRoutes.push(formattedMenu);
        }
      }

      console.log("生成的动态路由结果:", dynamicRoutes);
      return dynamicRoutes;
    },
    /** 前端登出（不调用接口） */
    logOut() {
      this.username = "";
      this.roles = [];
      this.permissions = [];
      this.menus = [];
      removeToken();
      usePermissionStoreHook().clearAllCachePage();
      useMultiTagsStoreHook().handleTags("equal", [...routerArrays]);
      resetRouter();
      router.push("/login");
    },
    /** 刷新`token` */
    async handRefreshToken(data) {
      return new Promise<RefreshTokenResult>((resolve, reject) => {
        refreshTokenApi(data)
          .then(data => {
            if (data) {
              setToken(data.data);
              resolve(data);
            }
          })
          .catch(error => {
            reject(error);
          });
      });
    }
  }
});

export function useUserStoreHook() {
  return useUserStore(store);
}
